<template>
  <div class="leaderboard-container">
    <div class="leaderboard-header">
      <div class="header-top">
        <h1 class="page-title">用户积分排行榜</h1>
      </div>
      <div class="filter-tabs">
        <span
          v-for="(period, idx) in timePeriods"
          :key="idx"
          :class="['filter-tab', { active: activePeriod === period.value }]"
          @click="activePeriod = period.value"
        >
          {{ period.label }}
        </span>
      </div>
    </div>

    <div v-loading="loading" class="leaderboard-content">
      <!-- 前三名特殊展示 -->
      <div v-if="leaderboardData.length > 0" class="top-players">
        <div
          v-for="(rank, index) in topThreePlayers"
          :key="rank.id"
          class="top-player"
          :class="`top-player-${index + 1}`"
        >
          <div class="rank-number">{{ index + 1 }}</div>
          <div class="avatar">
            <img :src="rank.avatar || defaultAvatar" alt="用户头像" />
            <div class="crown" :class="`crown-${index + 1}`">👑</div>
          </div>
          <div class="username">{{ rank.username }}</div>
          <div class="points">{{ rank.points }} 积分</div>
          <div class="edit-button">
            <el-button circle size="small" type="primary" @click="showEditDialog(rank)">
              <el-icon><Edit /></el-icon>
            </el-button>
          </div>
        </div>
      </div>

      <!-- 数据为空的提示 -->
      <el-empty v-if="!loading && leaderboardData.length === 0" description="暂无排行榜数据" />

      <!-- 其他排名列表 -->
      <div v-if="leaderboardData.length > 0" class="rank-list">
        <div class="rank-header">
          <span class="rank-col">排名</span>
          <span class="user-col">用户</span>
          <span class="points-col">积分</span>
          <span class="level-col">等级</span>
          <span class="trend-col">趋势</span>
          <span class="action-col">操作</span>
        </div>
        <div v-for="(player, index) in otherPlayers" :key="player.id" class="rank-item">
          <span class="rank-col">{{ index + 4 }}</span>
          <span class="user-col">
            <img class="mini-avatar" :src="player.avatar || defaultAvatar" alt="头像" />
            <span class="username-text">{{ player.username }}</span>
          </span>
          <span class="points-col">{{ player.points }}</span>
          <span class="level-col">
            <el-tag :type="getLevelType(player.level)">Lv.{{ player.level }}</el-tag>
          </span>
          <span class="trend-col">
            <i
              :class="[
                player.trend > 0
                  ? 'el-icon-top trend-up'
                  : player.trend < 0
                    ? 'el-icon-bottom trend-down'
                    : 'el-icon-minus trend-stable',
              ]"
            ></i>
            <span
              :class="[
                player.trend > 0 ? 'trend-up' : player.trend < 0 ? 'trend-down' : 'trend-stable',
              ]"
            >
              {{ Math.abs(player.trend) || "-" }}
            </span>
          </span>
          <span class="action-col">
            <el-button circle size="small" type="primary" @click="showEditDialog(player)">
              <el-icon><Edit /></el-icon>
            </el-button>
          </span>
        </div>
      </div>

      <!-- 我的排名 -->
      <div v-if="myRank && leaderboardData.length > 0" class="my-rank">
        <div class="divider">
          <span>我的排名</span>
        </div>
        <div class="rank-item highlight">
          <span class="rank-col">{{ myRank.rank }}</span>
          <span class="user-col">
            <img class="mini-avatar" :src="myRank.avatar || defaultAvatar" alt="头像" />
            <span class="username-text">{{ myRank.username }}</span>
          </span>
          <span class="points-col">{{ myRank.points }}</span>
          <span class="level-col">
            <el-tag :type="getLevelType(myRank.level)">Lv.{{ myRank.level }}</el-tag>
          </span>
          <span class="trend-col">
            <i
              :class="[
                myRank.trend > 0
                  ? 'el-icon-top trend-up'
                  : myRank.trend < 0
                    ? 'el-icon-bottom trend-down'
                    : 'el-icon-minus trend-stable',
              ]"
            ></i>
            <span
              :class="[
                myRank.trend > 0 ? 'trend-up' : myRank.trend < 0 ? 'trend-down' : 'trend-stable',
              ]"
            >
              {{ Math.abs(myRank.trend) || "-" }}
            </span>
          </span>
          <span class="action-col">
            <el-button circle size="small" type="primary" @click="showEditDialog(myRank)">
              <el-icon><Edit /></el-icon>
            </el-button>
          </span>
        </div>
      </div>
    </div>

    <!-- 编辑用户对话框 -->
    <el-dialog
      title="编辑用户信息"
      v-model="editDialogVisible"
      width="500px"
      destroy-on-close
    >
      <el-form :model="editForm" label-width="100px" :rules="editRules" ref="editFormRef">
        <el-form-item label="用户名称" prop="username">
          <el-input v-model="editForm.username" placeholder="请输入用户名称"></el-input>
        </el-form-item>
        <el-form-item label="头像" prop="avatar">
          <el-upload
            class="avatar-uploader"
            action="#"
            :show-file-list="false" 
            :auto-upload="false"
            :on-change="handleFileChange"
            :before-upload="beforeAvatarUpload"
          >
            <img v-if="editForm.avatar" :src="editForm.avatar" class="avatar-preview">
            <el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
          </el-upload>
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="editDialogVisible = false">取 消</el-button>
          <el-button type="primary" @click="submitEdit" :loading="editLoading">确 定</el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, watch, onMounted } from "vue";
import { ElMessage, ElForm, ElMessageBox } from "element-plus";
import { Edit, Plus } from '@element-plus/icons-vue';
import LeaderboardAPI, { type RankPlayer, type LeaderboardPeriod, type UserProfileForm } from "@/api/leaderboard";
import { useUserStore } from "@/store/modules/user";
import { getAccessToken } from "@/utils/auth";

interface TimePeriod {
  label: string;
  value: LeaderboardPeriod;
}

// 时间段选项
const timePeriods = ref<TimePeriod[]>([
  { label: "日榜", value: "daily" },
  { label: "周榜", value: "weekly" },
  { label: "月榜", value: "monthly" },
  { label: "总榜", value: "all" },
]);

// 当前选中的时间段
const activePeriod = ref<LeaderboardPeriod>("weekly");

// 默认头像
const defaultAvatar = "https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png";

// 排行榜数据
const leaderboardData = ref<RankPlayer[]>([]);
// 我的排名信息
const myRank = ref<(RankPlayer & { rank: number }) | null>(null);
// 加载状态
const loading = ref(false);

// 前三名玩家
const topThreePlayers = computed(() => {
  if (!leaderboardData.value || leaderboardData.value.length === 0) return [];
  return leaderboardData.value.slice(0, Math.min(3, leaderboardData.value.length));
});

// 第4名及之后的玩家
const otherPlayers = computed(() => {
  if (!leaderboardData.value || leaderboardData.value.length <= 3) return [];
  return leaderboardData.value.slice(3);
});

// 根据等级获取标签类型
const getLevelType = (level: number) => {
  if (!level) return "info";
  if (level >= 8) return "danger";
  if (level >= 5) return "warning";
  if (level >= 3) return "success";
  return "info";
};

// 获取排行榜数据
const fetchLeaderboardData = async (period: LeaderboardPeriod) => {
  loading.value = true;
  try {
    // 同时获取排行榜数据和我的排名信息
    console.log("开始请求排行榜数据...");

    try {
      const rankListResponse = await LeaderboardAPI.getRankList(period);
      console.log("排行榜数据获取成功:", rankListResponse);

      if (rankListResponse && Array.isArray(rankListResponse) && rankListResponse.length > 0) {
        leaderboardData.value = rankListResponse;
        ElMessage.success(`${getTimePeriodLabel(period)}排行榜数据加载成功`);
      } else {
        console.warn("排行榜返回数据为空");
        leaderboardData.value = [];
        ElMessage.warning(`${getTimePeriodLabel(period)}排行榜暂无数据`);
      }
    } catch (error) {
      console.error("获取排行榜列表失败:", error);
      leaderboardData.value = [];
      ElMessage.error("获取排行榜数据失败，请稍后重试");
    }

    try {
      const myRankResponse = await LeaderboardAPI.getMyRank(period);
      console.log("我的排名数据获取成功:", myRankResponse);

      if (myRankResponse && myRankResponse.id) {
        myRank.value = myRankResponse;
      } else {
        console.warn("我的排名返回数据无效");
        myRank.value = null;
      }
    } catch (error) {
      console.error("获取我的排名失败:", error);
      myRank.value = null;
    }
  } catch (error) {
    console.error("获取排行榜数据失败:", error);
    ElMessage.error("获取排行榜数据失败，请稍后重试");
    leaderboardData.value = [];
    myRank.value = null;
  } finally {
    loading.value = false;
  }
};

// 获取时间段标签
const getTimePeriodLabel = (value: LeaderboardPeriod): string => {
  const period = timePeriods.value.find((item) => item.value === value);
  return period ? period.label : "";
};

// 监听激活的时间段变化并获取相应数据
watch(activePeriod, (newValue) => {
  fetchLeaderboardData(newValue);
});

// 组件挂载时加载数据
onMounted(() => {
  fetchLeaderboardData(activePeriod.value);
});

// 编辑用户信息相关
const editDialogVisible = ref(false);
const editLoading = ref(false);
const userStore = useUserStore();
const editFormRef = ref<InstanceType<typeof ElForm> | null>(null);
const currentEditUser = ref<RankPlayer | null>(null);

// 编辑表单
const editForm = ref({
  userId: 0,
  username: '',
  avatar: ''
});

// 表单验证规则
const editRules = {
  username: [
    { required: true, message: '请输入用户名', trigger: 'blur' },
    { min: 2, max: 20, message: '长度在 2 到 20 个字符', trigger: 'blur' }
  ]
};

// 上传地址 - 使用环境变量中的API基础URL
const uploadUrl = import.meta.env.VITE_APP_API_URL + '/api/v1/game-files';

// 上传头部
const uploadHeaders = {
  Authorization: `Bearer ${getAccessToken()}`
};

// 显示编辑对话框
const showEditDialog = (user: RankPlayer) => {
  ElMessageBox.confirm(
    `确定要编辑用户 "${user.username}" 的信息吗？`,
    '确认操作',
    {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    }
  )
    .then(() => {
      currentEditUser.value = user;
      editForm.value = {
        userId: user.id,
        username: user.username,
        avatar: user.avatar || ''
      };
      editDialogVisible.value = true;
    })
    .catch(() => {
      ElMessage.info('已取消编辑操作');
    });
};

// 处理文件变化
const handleFileChange = (file: any) => {
  if (!file || !file.raw) {
    ElMessage.error('无法获取文件内容');
    return;
  }
  
  // 先检查文件类型和大小（虽然beforeAvatarUpload已经检查过，这里做双重保险）
  const isValidFile = beforeAvatarUpload(file.raw);
  if (!isValidFile) {
    return;
  }
  
  // 手动上传文件
  const formData = new FormData();
  formData.append('file', file.raw);
  
  console.log('准备上传文件:', file.name, '大小:', file.size / 1024, 'KB', '类型:', file.raw.type);
  console.log('上传URL:', uploadUrl);
  
  // 显示上传中
  editLoading.value = true;
  
  fetch(uploadUrl, {
    method: 'POST',
    headers: {
      Authorization: `Bearer ${getAccessToken()}`
    },
    body: formData
  })
  .then(response => {
    console.log('上传响应状态:', response.status, response.statusText);
    
    // 检查HTTP状态码
    if (response.status === 413) {
      throw new Error('文件太大，超出服务器允许的上传大小限制');
    } else if (!response.ok) {
      throw new Error(`服务器响应错误: ${response.status} ${response.statusText}`);
    }
    
    return response.json().catch(e => {
      console.error('解析响应JSON失败:', e);
      throw new Error('服务器返回的数据格式无效');
    });
  })
  .then(result => {
    editLoading.value = false;
    console.log('上传响应详情:', JSON.stringify(result));
    
    // 判断成功的条件 - 支持多种后端返回格式:
    if (result) {
      // 情况1: 标准 Result<T> 格式，检查 code
      if (result.code && ['00000', 0, 200].includes(result.code)) {
        if (typeof result.data === 'string' && result.data.includes('http')) {
          editForm.value.avatar = result.data;
          ElMessage.success('头像上传成功');
          return;
        }
      }
      
      // 情况2: 直接返回URL字符串
      if (typeof result === 'string' && result.includes('http')) {
        editForm.value.avatar = result;
        ElMessage.success('头像上传成功');
        return;
      }
      
      // 情况3: 包含URL属性的对象
      if (result.url && typeof result.url === 'string' && result.url.includes('http')) {
        editForm.value.avatar = result.url;
        ElMessage.success('头像上传成功');
        return;
      }
      
      // 无法识别的成功响应
      console.warn('无法从响应中提取URL:', result);
      ElMessage.warning('上传成功但无法获取图片URL');
    } else {
      ElMessage.error('服务器返回空响应');
    }
  })
  .catch(error => {
    console.error('上传异常:', error);
    editLoading.value = false;
    
    // 根据错误类型提供有用的错误消息
    if (error.message.includes('NetworkError') || error.name === 'TypeError') {
      ElMessage.error('网络错误，请检查网络连接');
    } else if (error.message.includes('413') || error.message.includes('太大')) {
      ElMessage.error('文件大小超出服务器限制，请选择小于5MB的图片');
    } else {
      ElMessage.error('上传过程中发生错误: ' + error.message);
    }
  });
};

// 头像上传前检查
const beforeAvatarUpload = (file: File) => {
  const isImage = file.type.startsWith('image/');
  const isLt5M = file.size / 1024 / 1024 < 5;

  if (!isImage) {
    ElMessage.error('上传头像图片只能是图片格式!');
    return false;
  }
  if (!isLt5M) {
    ElMessage.error('上传头像图片大小不能超过 5MB!');
    return false;
  }
  
  // 如果文件大于2MB，显示警告但仍允许上传
  if (file.size / 1024 / 1024 > 2) {
    ElMessage.warning('文件较大，上传可能需要较长时间');
  }
  
  return true;
};

// 提交编辑信息
const submitEdit = async () => {
  if (!editFormRef.value) return;
  
  try {
    const valid = await editFormRef.value.validate();
    if (valid) {
      editLoading.value = true;
      try {
        // 调用API更新用户信息
        const profileData: UserProfileForm = {
          userId: editForm.value.userId,
          username: editForm.value.username,
          avatar: editForm.value.avatar
        };
        
        console.log('提交用户资料：', profileData);
        const result = await LeaderboardAPI.updateUserProfile(profileData);
        console.log('更新用户资料响应：', result);
        
        if (result==null) {
          ElMessage.success('用户信息更新成功');
          editDialogVisible.value = false;
          
          // 如果编辑的是当前用户，更新store中的用户信息
          if (userStore.userInfo && userStore.userInfo.userId === editForm.value.userId) {
            userStore.userInfo.username = editForm.value.username;
            userStore.userInfo.avatar = editForm.value.avatar;
          }
          
          // 刷新排行榜数据以显示更新后的信息
          fetchLeaderboardData(activePeriod.value);
        } else {
          ElMessage.error('更新用户信息失败，请稍后重试');
        }
      } catch (error) {
        console.error('更新用户信息失败:', error);
        ElMessage.error('更新用户信息失败，请稍后重试');
      } finally {
        editLoading.value = false;
      }
    } else {
      ElMessage.warning('请正确填写表单信息');
    }
  } catch (error) {
    console.error('表单验证失败:', error);
    ElMessage.warning('请正确填写表单信息');
  }
};
</script>

<style scoped>
.leaderboard-container {
  width: 100%;
  max-width: 1200px;
  margin: 0 auto;
  padding: 20px;
  background-color: #f8f9fa;
}

.leaderboard-header {
  margin-bottom: 30px;
}

.header-top {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
}

.page-title {
  margin: 0;
  font-size: 32px;
  font-weight: 700;
  color: #333;
}

.filter-tabs {
  display: flex;
  gap: 16px;
  margin-bottom: 20px;
  border-bottom: 1px solid #eaeaea;
  padding-bottom: 10px;
}

/* 上传相关样式 */
.avatar-uploader {
  width: 178px;
  height: 178px;
  border: 1px dashed #d9d9d9;
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  transition: border-color 0.3s;
}

.avatar-uploader:hover {
  border-color: #409eff;
}

.avatar-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 178px;
  height: 178px;
  line-height: 178px;
  text-align: center;
}

.avatar-preview {
  width: 178px;
  height: 178px;
  display: block;
  object-fit: cover;
}

.dialog-footer {
  margin-top: 20px;
  text-align: right;
}

/* 原有样式保持不变 */
.filter-tab {
  padding: 8px 16px;
  cursor: pointer;
  font-size: 15px;
  border-radius: 20px;
  transition: all 0.3s ease;
  color: #666;
}

.filter-tab:hover {
  background-color: #f1f1f1;
  color: #333;
}

.filter-tab.active {
  background-color: #333;
  color: white;
  font-weight: 500;
}

/* 前三名样式 */
.top-players {
  display: flex;
  justify-content: center;
  align-items: flex-end;
  margin-bottom: 40px;
  padding: 0 20px;
}

.top-player {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 20px;
  background-color: white;
  border-radius: 12px;
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.05);
  transition: all 0.3s ease;
}

.top-player:hover {
  transform: translateY(-5px);
  box-shadow: 0 12px 24px rgba(0, 0, 0, 0.1);
}

.top-player-1 {
  order: 2;
  margin: 0 -5px;
  padding-top: 30px;
  z-index: 3;
  transform: scale(1.1);
  border: 2px solid gold;
}

.top-player-2 {
  order: 1;
  z-index: 2;
  margin-bottom: 10px;
  border: 2px solid silver;
}

.top-player-3 {
  order: 3;
  z-index: 1;
  margin-bottom: 10px;
  border: 2px solid #cd7f32; /* 铜色 */
}

.rank-number {
  position: absolute;
  top: -15px;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background-color: #333;
  color: white;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: bold;
  font-size: 16px;
}

.top-player-1 .rank-number {
  background-color: gold;
  color: #333;
}

.top-player-2 .rank-number {
  background-color: silver;
  color: #333;
}

.top-player-3 .rank-number {
  background-color: #cd7f32;
  color: white;
}

.avatar {
  position: relative;
  width: 80px;
  height: 80px;
  margin-bottom: 10px;
}

.top-player-1 .avatar {
  width: 100px;
  height: 100px;
}

.avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 50%;
  border: 2px solid #eee;
}

.crown {
  position: absolute;
  top: -15px;
  left: 50%;
  transform: translateX(-50%);
  font-size: 20px;
}

.crown-1 {
  font-size: 24px;
}

.username {
  font-weight: bold;
  font-size: 16px;
  margin: 5px 0;
  color: #333;
}

.top-player-1 .username {
  font-size: 18px;
}

.points {
  font-size: 14px;
  color: #666;
}

.top-player-1 .points {
  color: gold;
  font-weight: bold;
}

.edit-button {
  margin-top: 10px;
}

/* 排行榜列表样式 */
.rank-list {
  background-color: white;
  border-radius: 12px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.05);
  overflow: hidden;
  margin-bottom: 20px;
}

.rank-header {
  display: flex;
  background-color: #f5f7fa;
  padding: 15px;
  font-weight: bold;
  color: #606266;
  border-bottom: 1px solid #ebeef5;
}

.rank-item {
  display: flex;
  padding: 15px;
  align-items: center;
  border-bottom: 1px solid #ebeef5;
  transition: background-color 0.3s;
}

.rank-item:last-child {
  border-bottom: none;
}

.rank-item:hover {
  background-color: #f9fafc;
}

.rank-item.highlight {
  background-color: #ecf5ff;
}

.rank-col {
  width: 80px;
  text-align: center;
  font-weight: 500;
}

.user-col {
  flex: 1;
  display: flex;
  align-items: center;
}

.mini-avatar {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  margin-right: 10px;
  object-fit: cover;
}

.username-text {
  font-weight: 500;
}

.points-col {
  width: 100px;
  text-align: center;
  font-weight: 500;
}

.level-col {
  width: 100px;
  text-align: center;
}

.trend-col {
  width: 100px;
  text-align: center;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 5px;
}

.action-col {
  width: 80px;
  text-align: center;
}

.trend-up {
  color: #67c23a;
}

.trend-down {
  color: #f56c6c;
}

.trend-stable {
  color: #909399;
}

/* 我的排名样式 */
.my-rank {
  margin-top: 30px;
}

.divider {
  display: flex;
  align-items: center;
  margin: 16px 0;
  color: #909399;
}

.divider:before,
.divider:after {
  content: "";
  flex: 1;
  border-top: 1px solid #dcdfe6;
}

.divider span {
  padding: 0 16px;
  font-weight: 500;
}
</style>
